#pragma once

#include <vector>
#include <string>
#include <map>
#include <unordered_map>

#include "RelationshipType.h"
#include "RelationshipArgumentType.h"
#include "RelationshipEntry.h"

// RelationshipClauseTable is used by the QueryPreprocessor
// to store the relationship clauses queried
// in the following format (inside RelationshipEntry data structure)
//	RelationshipType - Argument 1 - Argument 2 - Argument Type 1 - Argument Type 2
// RelationshipClauseTable will then be used by QueryEvaluator for evaluation the queries about these relationships.
class RelationshipClauseTable {
	private:
		std::vector<RelationshipEntry> mRelationshipEntries;
		std::unordered_map<RelationshipEntry, int> mRelationshipEntryMap;

	public:
		RelationshipClauseTable(void);
		~RelationshipClauseTable(void);

		/// Adds a RelationshipEntry into the table, returning true if successful (if all inputs are non-null and non-empty).
		/// Returns false if there is any null/empty inputs.
		bool addRelationshipEntry(RelationshipType relationshipType, 
			std::string relationshipArg1, RelationshipArgumentType relationshipArgType1,
			std::string relationshipArg2, RelationshipArgumentType relationshipArgType2);

		/// Check if a relationship entry already exists. Return true if it already exists.
		bool existRelationshipEntry(RelationshipType relationshipType, 
			std::string relationshipArg1, RelationshipArgumentType relationshipArgType1,
			std::string relationshipArg2, RelationshipArgumentType relationshipArgType2);

		/// Replace Synonym s2 with s1
		bool replaceSynonym(std::string s1, std::string s2);

		bool removeRedundancy();

		/// Returns the RelationshipEntry at the specifed index.
		/// Returns an empty RelationshipEntry if index is out of bounds.
		RelationshipEntry getRelationshipEntry(int index);
		/// Gets the number of entries currently in the table. 
		int getNumberOfEntries();
};

